#pragma once
#include <cmath>
#include <iostream>
using namespace std;

namespace Course
{
	namespace adt
	{
		template<class T>

		class interval
		{
		private:
			T lower;
			T upper;
		public:

			interval(void)
			{
				lower = upper = 0;
			}
			interval(T mean , double procent)
			{
				lower = mean - mean*procent/100.0 ;
				upper = mean + mean*procent/100.0 ;
			}

			T mean() 
			{ return (lower , upper) /2;}

			double relativ_error() 
			{ return (upper -lower) / mean();}

			
			friend interval<T> operator+ (interval<T> &lop , interval<T> & rop)
			{
				interval<T> m;
				m.lower = lop.lower+rop.lower;
				m.upper = lop.upper + rop.upper;
				
				return m;
			}
			friend interval<T> operator- (interval<T> &lop , interval<T> & rop)
			{
				interval<T> m;
				m.lower = lop.lower-rop.upper;
				m.upper = lop.upper -rop.lower;
				return m;
			}
			friend interval<T> operator* (interval<T> &lop , interval<T> & rop)
			{
				interval<T> m;
				m.lower = min(min(min(lop.lower * rop.lower, lop.lower *rop.upper), lop.upper* rop.lower) , lop.upper* rop.upper);
				m.upper = max(max(max(lop.lower * rop.lower, lop.lower *rop.upper), lop.upper* rop.lower) , lop.upper* rop.upper);
				return m;
			}
			friend interval<T> operator/ (interval<T> &lop , interval<T> & rop)
			{
				interval<T> m;
				m.lower = min(min(min(lop.lower / rop.lower, lop.lower / rop.upper), lop.upper / rop.lower) , lop.upper/ rop.upper);
				m.upper = max(max(max(lop.lower / rop.lower, lop.lower / rop.upper), lop.upper / rop.lower) , lop.upper/ rop.upper);
				return m;
			}
			friend ostream& operator <<(ostream &out , const interval<T> &rop)
			{
				out <<"[" << rop.lower << "," << rop.upper <<"]";
				return out;
			}
			

			~interval(void)
			{
			}
		};
	}
}